From a7b334620e9696e809dbbcbdb81816120470939c Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 18 Feb 2026 17:19:07 +0100 Subject: [PATCH] [PATCH] krb5: use app-layer incomplete support Ticket: 3540 Ticket: 8305 (cherry picked from commit 8e886a8ecdb5d0b21568be489686a7e0f8136e58) Origin: upstream, https://github.com/OISF/suricata/commit/4c51a74e2e3a06d352dcac5a720450a392c5c5b2.patch Bug: https://redmine.openinfosecfoundation.org/issues/8307 Subject: Upstream fix for CVE-2026-31932 Gbp-Pq: Name CVE-2026-31932.patch --- rust/src/krb/krb5.rs | 66 +++++++++++--------------------------------- 1 file changed, 16 insertions(+), 50 deletions(-) diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 9ff0ff21..6d977758 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -41,9 +41,7 @@ pub struct KRB5State { pub req_id: u8, pub record_ts: usize, - pub defrag_buf_ts: Vec, pub record_tc: usize, - pub defrag_buf_tc: Vec, /// List of transactions for this session transactions: Vec, @@ -109,9 +107,7 @@ impl KRB5State { state_data: AppLayerStateData::new(), req_id: 0, record_ts: 0, - defrag_buf_ts: Vec::new(), record_tc: 0, - defrag_buf_tc: Vec::new(), transactions: Vec::new(), tx_id: 0, } @@ -463,25 +459,9 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow, stream_slice: StreamSlice, _data: *const std::os::raw::c_void, ) -> AppLayerResult { - let state = cast_pointer!(state,KRB5State); - let buf = stream_slice.as_slice(); - - let mut v : Vec; - let tcp_buffer = match state.record_ts { - 0 => buf, - _ => { - // sanity check to avoid memory exhaustion - if state.defrag_buf_ts.len() + buf.len() > 100000 { - SCLogDebug!("rs_krb5_parse_request_tcp: TCP buffer exploded {} {}", - state.defrag_buf_ts.len(), buf.len()); - return AppLayerResult::err(); - } - v = state.defrag_buf_ts.split_off(0); - v.extend_from_slice(buf); - v.as_slice() - } - }; - let mut cur_i = tcp_buffer; + let state = cast_pointer!(state, KRB5State); + let mut cur_i = stream_slice.as_slice(); + let start_len = cur_i.len(); while !cur_i.is_empty() { if state.record_ts == 0 { match be_u32(cur_i) as IResult<&[u8],u32> { @@ -490,8 +470,7 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow, cur_i = rem; }, Err(Err::Incomplete(_)) => { - state.defrag_buf_ts.extend_from_slice(cur_i); - return AppLayerResult::ok(); + return AppLayerResult::incomplete((start_len - cur_i.len()) as u32, 4u32); } _ => { SCLogDebug!("rs_krb5_parse_request_tcp: reading record mark failed!"); @@ -507,8 +486,10 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow, cur_i = &cur_i[state.record_ts..]; } else { // more fragments required - state.defrag_buf_ts.extend_from_slice(cur_i); - return AppLayerResult::ok(); + return AppLayerResult::incomplete( + (start_len - cur_i.len()) as u32, + state.record_ts as u32, + ); } } AppLayerResult::ok() @@ -521,25 +502,9 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow, stream_slice: StreamSlice, _data: *const std::os::raw::c_void, ) -> AppLayerResult { - let state = cast_pointer!(state,KRB5State); - let buf = stream_slice.as_slice(); - - let mut v : Vec; - let tcp_buffer = match state.record_tc { - 0 => buf, - _ => { - // sanity check to avoid memory exhaustion - if state.defrag_buf_tc.len() + buf.len() > 100000 { - SCLogDebug!("rs_krb5_parse_response_tcp: TCP buffer exploded {} {}", - state.defrag_buf_tc.len(), buf.len()); - return AppLayerResult::err(); - } - v = state.defrag_buf_tc.split_off(0); - v.extend_from_slice(buf); - v.as_slice() - } - }; - let mut cur_i = tcp_buffer; + let state = cast_pointer!(state, KRB5State); + let mut cur_i = stream_slice.as_slice(); + let start_len = cur_i.len(); while !cur_i.is_empty() { if state.record_tc == 0 { match be_u32(cur_i) as IResult<&[u8],_> { @@ -548,8 +513,7 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow, cur_i = rem; }, Err(Err::Incomplete(_)) => { - state.defrag_buf_tc.extend_from_slice(cur_i); - return AppLayerResult::ok(); + return AppLayerResult::incomplete((start_len - cur_i.len()) as u32, 4u32); } _ => { SCLogDebug!("reading record mark failed!"); @@ -565,8 +529,10 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow, cur_i = &cur_i[state.record_tc..]; } else { // more fragments required - state.defrag_buf_tc.extend_from_slice(cur_i); - return AppLayerResult::ok(); + return AppLayerResult::incomplete( + (start_len - cur_i.len()) as u32, + state.record_tc as u32, + ); } } AppLayerResult::ok() -- 2.30.2